package com.ruoyi.cost.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.cost.domain.ModeParams;
import com.ruoyi.cost.domain.SubTree;
import org.apache.ibatis.annotations.Param;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.cost.domain.AccSubject;
import com.ruoyi.cost.service.IAccSubjectService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 会计科目Controller
 *
 * @author 王志旸
 * @date 2024-07-09
 */
@RestController
@RequestMapping("/cost/subject")
public class AccSubjectController extends BaseController {
    @Autowired
    private IAccSubjectService accSubjectService;

    /**
     * 查询会计科目列表
     */
//    @PreAuthorize("@ss.hasPermi('cost:subject:list')")
    @GetMapping("/list")
    public TableDataInfo list(AccSubject accSubject) {
        startPage();
        List<AccSubject> list = accSubjectService.selectAccSubjectList(accSubject);
        return getDataTable(list);
    }

//    @PreAuthorize("@ss.hasPermi('cost:subject:list')")
    @GetMapping("/listTree1")
    public AjaxResult listTree1(ModeParams modeParams) {

        List<AccSubject> list = accSubjectService.listTree(modeParams.getFilterText(), modeParams.getAccMode());
        ArrayList<Integer> objects = new ArrayList<>();
        objects.add(4);
        objects.add(2);
        objects.add(2);
        objects.add(2);
        objects.add(2);
        buildTree(list,objects);
        List<SubTree> subTrees = buildTree1(list, objects);
        SubTree subTree = new SubTree();
        subTree.setLabel("全部");
        subTree.setId(0);
        subTree.setValue("-1");
        subTree.setChildren(subTrees);
        ArrayList<SubTree> subTrees1 = new ArrayList<>();
        subTrees1.add(subTree);
        return success(subTrees1);
    }

//    @PreAuthorize("@ss.hasPermi('cost:subject:list')")
    @GetMapping("/listTree2")
    public AjaxResult listTree2(ModeParams modeParams) {

        List<AccSubject> list = accSubjectService.listTree(modeParams.getFilterText(), modeParams.getAccMode());
        ArrayList<Integer> objects = new ArrayList<>();
        objects.add(4);
        objects.add(2);
        objects.add(2);
        objects.add(2);
        objects.add(2);
        buildTree(list,objects);
        List<SubTree> subTrees = buildTree(list, objects);
        setChildren(subTrees);
        return success(subTrees);
    }

    private void setChildren(List<SubTree> subTrees) {
        for (SubTree subTree : subTrees) {
            List<SubTree> children = subTree.getChildren();
            if (children != null && !children.isEmpty()) {
                // 递归调用处理子节点
                setChildren(children);
            } else {
                // 当没有子节点时，将 children 设置为 null
                subTree.setChildren(null);
            }
        }
    }


//    @PreAuthorize("@ss.hasPermi('cost:subject:list')")
    @GetMapping("/listTree")
    public AjaxResult listTree(ModeParams modeParams) {
        if (modeParams.getAccMode() != null && modeParams.getAccMode().equals("0")){
            modeParams.setAccMode(null);
        }
        List<AccSubject> list = accSubjectService.listTree(modeParams.getFilterText(), modeParams.getAccMode());
        ArrayList<Integer> objects = new ArrayList<>();
        objects.add(4);
        objects.add(2);
        objects.add(2);
        objects.add(2);
        objects.add(2);
        buildTree(list,objects);
        List<SubTree> subTrees = buildTree(list, objects);
        SubTree subTree = new SubTree();
        subTree.setLabel("全部");
        subTree.setId(0);
        subTree.setValue("-1");
        subTree.setChildren(subTrees);
        ArrayList<SubTree> subTrees1 = new ArrayList<>();
        subTrees1.add(subTree);
        return success(subTrees1);
    }

    public List<SubTree> buildTree(List<AccSubject> accSubjects, List<Integer> levelRules) {
        Map<String, SubTree> nodeMap = new HashMap<>();
        List<SubTree> rootNodes = new ArrayList<>();
        int idCounter = 1;
        for (AccSubject accSubject : accSubjects) {
            SubTree node = new SubTree();
            node.setId(idCounter++);
            node.setLabel(accSubject.getAccSubNum()+"    "+accSubject.getAccSubName());
            node.setValue(accSubject.getAccSubNum());
            nodeMap.put(accSubject.getAccSubNum(), node);

            String accSubNum = accSubject.getAccSubNum();
            int level = getLevel(accSubNum, levelRules);

            if (level == 0) {
                rootNodes.add(node);  // 根节点
            } else {
                String parentNum = accSubNum.substring(0, getParentLength(levelRules, level));
                SubTree parentNode = nodeMap.get(parentNum);
                if (parentNode != null) {
                    parentNode.getChildren().add(node);
                }
            }
        }
        return rootNodes;
    }

    public List<SubTree> buildTree1(List<AccSubject> accSubjects, List<Integer> levelRules) {
        Map<String, SubTree> nodeMap = new HashMap<>();
        List<SubTree> rootNodes = new ArrayList<>();
        int idCounter = 1;
        for (AccSubject accSubject : accSubjects) {
            SubTree node = new SubTree();
            node.setId(idCounter++);
            node.setLabel(accSubject.getAccSubNum()+"    "+accSubject.getAccSubName());
            node.setSubName(accSubject.getAccSubName());
            node.setValue(accSubject.getAccSubNum());
            nodeMap.put(accSubject.getAccSubNum(), node);

            String accSubNum = accSubject.getAccSubNum();
            int level = getLevel(accSubNum, levelRules);

            // 只处理前两级
            if (level < 1) {
                if (level == 0) {
                    rootNodes.add(node);  // 根节点
                } else {
                    String parentNum = accSubNum.substring(0, getParentLength(levelRules, level));
                    SubTree parentNode = nodeMap.get(parentNum);
                    if (parentNode != null) {
                        parentNode.getChildren().add(node);
                    }
                }
            }
        }
        return rootNodes;
    }

    private int getLevel(String accSubNum, List<Integer> levelRules) {
        int length = 0;
        for (int i = 0; i < levelRules.size(); i++) {
            length += levelRules.get(i);
            if (accSubNum.length() == length) {
                return i;
            }
        }
        return -1; // Invalid level
    }

    private int getParentLength(List<Integer> levelRules, int level) {
        int length = 0;
        for (int i = 0; i < level; i++) {
            length += levelRules.get(i);
        }
        return length;
    }


    /**
     * 导出会计科目列表
     */
//    @PreAuthorize("@ss.hasPermi('cost:subject:export')")
    @Log(title = "会计科目", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AccSubject accSubject) {
        List<AccSubject> list = accSubjectService.selectAccSubjectList(accSubject);
        ExcelUtil<AccSubject> util = new ExcelUtil<AccSubject>(AccSubject.class);
        util.exportExcel(response, list, "会计科目数据");
    }

    /**
     * 获取会计科目详细信息
     */
//    @PreAuthorize("@ss.hasPermi('cost:subject:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(accSubjectService.selectAccSubjectById(id));
    }

    /**
     * 新增会计科目
     */
//    @PreAuthorize("@ss.hasPermi('cost:subject:add')")
    @Log(title = "会计科目", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AccSubject accSubject) {
        return toAjax(accSubjectService.insertAccSubject(accSubject));
    }

    /**
     * 修改会计科目
     */
//    @PreAuthorize("@ss.hasPermi('cost:subject:edit')")
    @Log(title = "会计科目", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AccSubject accSubject) {
        return toAjax(accSubjectService.updateAccSubject(accSubject));
    }

    /**
     * 删除会计科目
     */
//    @PreAuthorize("@ss.hasPermi('cost:subject:remove')")
    @Log(title = "会计科目", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(accSubjectService.deleteAccSubjectByIds(ids));
    }
}
